"""
python fujian3_genetic_nolib.py
"""


import json
import random

random.seed(114514)

# 读取仓库信息
def read_warehouse_data():
    with open('../fujian/fujian3/origin_data/warehouse.json') as f:
        return json.load(f)

# 读取品类平均库存量
def read_category_inventory():
    with open('../fujian/fujian3/data_from_p1/all_average_inventory.json') as f:
        return {d['category_id']: d['average_inventory'] for d in json.load(f)}

# 读取品类平均销量
def read_category_sales():
    with open('../fujian/fujian3/data_from_p1/all_average_sales.json') as f:
        return {d['category_id']: d['average_sales'] for d in json.load(f)}

warehouses = read_warehouse_data()
category_inventories = read_category_inventory()
category_sales = read_category_sales()

# 染色体编码
def generate_chromosome():
    return [random.choice(range(len(warehouses))) for _ in category_inventories]

# 种群生成
def generate_population(size):
    return [generate_chromosome() for _ in range(size)]

# 计算适应度
def fitness(chromosome):
    total_cost = 0
    warehouse_inventories = [0] * len(warehouses)
    warehouse_sales = [0] * len(warehouses)
    for category_index, warehouse_index in enumerate(chromosome):
        warehouse_inventories[warehouse_index] += category_inventories[str(category_index + 1)]
        warehouse_sales[warehouse_index] += category_sales[str(category_index + 1)]
    for warehouse_index, warehouse in enumerate(warehouses):
        if warehouse_inventories[warehouse_index] > warehouse['max_inventory'] or warehouse_sales[warehouse_index] > warehouse['max_sales']:
            return float('inf')
        if warehouse_inventories[warehouse_index] > 0:
            total_cost += warehouse['daily_cost']
    return total_cost

# 选择操作
def selection(population):
    fitnesses = [fitness(chromosome) for chromosome in population]
    total_fitness = sum(fitnesses)
    probabilities = [fitness / total_fitness for fitness in fitnesses]
    return random.choices(population, weights=probabilities, k=len(population))

# 交叉操作
def crossover(parent1, parent2):
    point = random.randint(0, len(parent1) - 1)
    child1 = parent1[:point] + parent2[point:]
    child2 = parent2[:point] + parent1[point:]
    return child1, child2

# 变异操作
def mutation(chromosome):
    index = random.randint(0, len(chromosome) - 1)
    chromosome[index] = random.choice(range(len(warehouses)))
    return chromosome

# 遗传算法
def genetic_algorithm():
    population_size = 100
    generations = 100
    population = generate_population(population_size)
    for _ in range(generations):
        population = selection(population)
        new_population = []
        while len(new_population) < population_size:
            parent1, parent2 = random.choices(population, k=2)
            child1, child2 = crossover(parent1, parent2)
            child1 = mutation(child1)
            child2 = mutation(child2)
            new_population.append(child1)
            new_population.append(child2)
        population = new_population
    best_chromosome = min(population, key=fitness)
    return best_chromosome

# 生成结果 JSON
def generate_result(chromosome):
    result = []
    for category_index, warehouse_index in enumerate(chromosome):
        result.append({
            "category_id": str(category_index + 1),
            "warehouse_id": warehouses[warehouse_index]['warehouse_id']
        })
    return result

best_chromosome = genetic_algorithm()
result_json = generate_result(best_chromosome)
print(json.dumps(result_json, indent=4))
